#pragma once

#define DATASIZE 5000

namespace Core
{

	/**
	 * Kelas yang menampung data mentah berupa array of bytes
	 */
	class RawData
	{
	private:
		unsigned char	m_Data[DATASIZE];	///Menyimpan raw data
		unsigned short	m_Size;   ///Menyimpan panjang
		unsigned short	m_ReadIterator;	///Menyimpan index baca terakhir yang bertambah secara otomatis
		unsigned short	m_WriteIterator;	///Menyimpan index tulis terakhir yang bertambah secara otomatis

	protected:

	public:
		/**
		 * Konstruktor dasar
		 * Mod by OS: reset Iterator terpanggil pada fungsi ini, seluruh m_data terinisiasi dengan 0
		 */
		RawData();

		/**
		 * Destruktor
		 * Menghapus data yang ada dalam raw data (gunakan delete), m_data diassign ke NULL
		 */
		~RawData();

		/**
		 * Fungsi yang menghitung panjang raw data
		 * @return Panjang raw data
		 */
		unsigned short GetSize() const;

		unsigned short GetLength() const;

		unsigned short GetRemaining() const;

		/**
		 * Fungsi yang menyatakan apakah data terisi penuh
		 * @return Apakah data terisi penuh
		 */
		bool IsFull() const;

		void Reset();

		void ResetWriteIterator();

		/**
		 * Fungsi yang mengembalikan iterator baca ke 0
		 */
		void ResetReadIterator();

		unsigned char PeekChar();

		/**
		 * Fungsi yang membaca karakter pada raw data sepanjang 1 byte, iterator bertambah
		 * @return Karakter yang dibaca pada index terakhir sepanjang 1 byte
		 */
		unsigned char ReadChar();

		/**
		 * Fungsi yang menulis karakter pada raw data sepanjang 1 byte, iterator bertambah
		 * @param p_Data data yang akan dituliskan
		 */
		void WriteChar(unsigned char p_Data);

		/**
		 * Fungsi yang membaca karakter pada raw data sepanjang 2 byte, iterator bertambah
		 * Mod by OS: Harap perhatikan big endian dan little endian
		 * @return Karakter yang dibaca pada index terakhir sepanjang 2 byte
		 */
		unsigned short ReadShort();

		/**
		 * Fungsi yang menulis karakter pada raw data sepanjang 2 byte, iterator bertambah
		 * Mod by OS: Harap perhatikan big endian dan little endian
		 * @param p_Data data yang akan dituliskan
		 */
		void WriteShort(unsigned short p_Data);

		unsigned long Read24Bit();

		void Write24Bit(unsigned long p_24bit);

		/**
		 * Fungsi yang membaca karakter pada raw data sepanjang 4 byte, iterator bertambah
		 * Mod by OS: Harap perhatikan big endian dan little endian
		 * @return Karakter yang dibaca pada index terakhir sepanjang 4 byte
		 */
		unsigned long ReadLong();

		/**
		 * Fungsi yang menulis karakter pada raw data sepanjang 4 byte, iterator bertambah
		 * Mod by OS: Harap perhatikan big endian dan little endian
		 * @param p_Data data yang akan dituliskan
		 */
		void WriteLong(unsigned long p_Data);

		unsigned short ReadFromMemory(unsigned char*& p_Data, unsigned short p_Length);

		unsigned short WriteToMemory(unsigned char*& p_Data, unsigned short p_Length);

		void ReadFromIStream(std::istream& p_IStream, unsigned short p_Length);

		void WriteToOStream(std::ostream& p_OStream, unsigned short p_Length);

		unsigned char& operator[](unsigned short p_Index);

		unsigned short GetReadIterator() const;

		void SetReadIterator(unsigned short p_Index);

		unsigned short GetWriteIterator() const;

		void SetWriteIterator(unsigned short p_Index);

		void FromString(std::string p_String);

		std::string ToString() const;

		std::string ToHexString();
	};
}
